package com.lehecai.ucenter.service.impl.permission;

import com.lehecai.core.EnabledStatus;
import com.lehecai.core.util.CharsetConstant;
import com.lehecai.core.util.CoreStringUtils;
import com.lehecai.ucenter.dao.QueryParam;
import com.lehecai.ucenter.dao.app.AppDao;
import com.lehecai.ucenter.dao.permission.RoleDao;
import com.lehecai.ucenter.dao.permission.UserAppDao;
import com.lehecai.ucenter.dao.permission.UserDao;
import com.lehecai.ucenter.dao.permission.UserRoleDao;
import com.lehecai.ucenter.entity.app.App;
import com.lehecai.ucenter.entity.permission.Role;
import com.lehecai.ucenter.entity.permission.User;
import com.lehecai.ucenter.entity.permission.UserApp;
import com.lehecai.ucenter.entity.permission.UserRole;
import com.lehecai.ucenter.service.permission.UserService;
import com.lehecai.ucenter.utils.PageBean;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserServiceImpl implements UserService {
	
	private UserDao userDao;
	private RoleDao roleDao;
	private UserRoleDao userRoleDao;
	private UserAppDao userAppDao;
	private AppDao appDao;
	
	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}
	
	public UserRoleDao getUserRoleDao() {
		return userRoleDao;
	}

	public void setUserRoleDao(UserRoleDao userRoleDao) {
		this.userRoleDao = userRoleDao;
	}

	public RoleDao getRoleDao() {
		return roleDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	public UserAppDao getUserAppDao() {
		return userAppDao;
	}

	public void setUserAppDao(UserAppDao userAppDao) {
		this.userAppDao = userAppDao;
	}

	public AppDao getAppDao() {
		return appDao;
	}

	public void setAppDao(AppDao appDao) {
		this.appDao = appDao;
	}

	@Override
	public User login(String username, String password){
		User user = findByUsername(username);
		if(user != null && user.getId() != null && user.getEnabled().getValue() == EnabledStatus.ENABLED.getValue()){
			if(CoreStringUtils.md5(password, CharsetConstant.CHARSET_UTF8).equals(user.getPassword())){
				return user;
			}
		}
		return null;
	}
	
	@Override
	public User update(User user) {
		return userDao.merge(user);
	}
	
	@Override
	public void update(UserRole userRole) {
		User user = new User();
		user.setId(userRole.getUserId());
		UserRole dbUserRole = findUserRoleByUser(user);
		if(dbUserRole == null){
			dbUserRole = userRole;
		}else{
			dbUserRole.setRoleId(userRole.getRoleId());
		}
		userRoleDao.merge(dbUserRole);
	}
	
	@Override
	public List<User> findList(QueryParam queryParam) {
		List<User> users = userDao.findList(queryParam);
		int totalCount = userDao.count(queryParam);
		PageBean pageBean = queryParam.getPageBean();
		if(pageBean != null){
			pageBean.setCount(totalCount);
			int pageCount = 0;//页数
			if(pageBean.getPageSize() != 0) {
	            pageCount = totalCount / pageBean.getPageSize();
	            if(totalCount % pageBean.getPageSize() != 0) {
	                pageCount ++;
	            }
	        }
			pageBean.setPageCount(pageCount);
		}
		return users;
	}
	
	@Override
	public User findByUsername(String username) {
		QueryParam queryParam = new QueryParam();
		queryParam.setParameter(User.USER_NAME_PROPERTY_NAME, username);
		List<User> list = userDao.findList(queryParam);
		if (list != null && list.size() != 0) {
			return list.get(0);
		}else{
			return null;
		}
	}

	@Override
	public User get(Long id) {
		return userDao.get(id);
	}

	@Override
	public void delete(User user) {
		userDao.delete(user);
	}
	
	@Override
	public UserRole findUserRoleByUser(User user) {
		QueryParam queryParam = new QueryParam();
		queryParam.setParameter(UserRole.USER_ID_PROPERTY_NAME, user.getId());
		List<UserRole> userRoles = userRoleDao.findList(queryParam);
		if(userRoles == null || userRoles.isEmpty()) {
			return null;
		}else{
			return userRoles.get(0);
		}
	}
	
	@Override
	public Role findRoleByUser(User user) {
		QueryParam queryParam = new QueryParam();
		queryParam.setParameter(UserRole.USER_ID_PROPERTY_NAME, user.getId());
		List<UserRole> userRoles = userRoleDao.findList(queryParam);
		if(userRoles == null || userRoles.isEmpty()) {
			return null;
		}
		Role role = roleDao.get(userRoles.get(0).getRoleId());
		return role;
	}
	
	@Override
	public List<App> findAppsByUser(User user) {
		QueryParam queryParam = new QueryParam();
		queryParam.setParameter(UserApp.USER_ID_PROPERTY_NAME, user.getId());
		List<UserApp> userApps = userAppDao.findList(queryParam);
		if(userApps == null || userApps.isEmpty()) {
			return null;
		}
		List<App> apps = new ArrayList<App>();
		for(UserApp userApp : userApps){
			App app = appDao.get(userApp.getAppId());
			apps.add(app);
		}
		return apps;
	}
	
	@Override
	public void manage(UserApp userApp){
		User user = userDao.get(userApp.getUserId());
		List<App> dispatchedApps = findAppsByUser(user);
		if(dispatchedApps == null){
			dispatchedApps = new ArrayList<App>();
		}
		boolean isExist = false;
		for(App dispatchedApp : dispatchedApps){
			if(dispatchedApp.getId().longValue() == userApp.getAppId().longValue()){
				isExist = true;
				break;
			}
		}
		if(!isExist){
			userAppDao.merge(userApp);
		}
	}
	
	@Override
	public void del(UserApp userApp){
		QueryParam queryParam = new QueryParam();
		queryParam.setParameter(UserApp.USER_ID_PROPERTY_NAME, userApp.getUserId());
		queryParam.setParameter(UserApp.APP_ID_PROPERTY_NAME, userApp.getAppId());
		List<UserApp> userApps = userAppDao.findList(queryParam);
		if(userApps != null && !userApps.isEmpty()) {
			for(UserApp ua : userApps){
				userAppDao.delete(ua);
			}
		}
	}

    @Override
    public Map<Long, Role> getUserRoleMap() {
        QueryParam queryParam = new QueryParam();
        List<UserRole> userRoles = userRoleDao.findList(queryParam);
        List<Role> roles = roleDao.getAll();
        Map<Long, Role> roleMap = new HashMap<Long, Role>();
        if (roles != null) {
            for (Role role : roles) {
                roleMap.put(role.getId(), role);
            }
        }
        Map<Long, Role> map = new HashMap<Long, Role>();
        if (userRoles != null) {
            for (UserRole userRole : userRoles) {
                Long roleId = userRole.getRoleId();
                Long userId = userRole.getUserId();
                Role tempRole = roleMap.get(roleId);
                if (tempRole != null) {
                    map.put(userId, tempRole);
                }
            }
        }
        return map;
    }
}
